var UUID = require("uuid")
var errorLogger = require("pomelo-logger").getLogger("error-log");
//匹配管理器
var checkpointMatch = require("./matchType/checkpointMatch.js")
var runQuicklyNormal = require("./matchType/runQuicklyNormal.js")
var goldMatch = require("./matchType/goldMatch.js")
var competitionMatch = require("./matchType/competitionSuper.js")
var robotData = require("../../../conf/robot.json")
var runQuicklyGoldCfg = require("./cfg/runQuicklyGold.json")
var UNOGoldCfg = require("./cfg/UNOGold.json")
var competitionCfg = require("./cfg/competition.json")
var maxRobotNum = robotData.length
var curRobotNum = Math.floor(Math.random() * maxRobotNum)
module.exports = function(app){
	console.log("checkpointMatch!!!")
	var matchMap = {
		"hunanRunQuicklyCheckpoint" : checkpointMatch,
		"hunanRunQuickly" : runQuicklyNormal
	}
	var matchTypeList = {}      //匹配房间列表
	var matchGoldUserNum = {} 	//金币场人数
	var freePlayCounts = {} 	//比赛场免费参玩次数
	var freePlayDate = -1 		//免费场记录时间
	var matchGoldUserStandard = {	//人数基准
		"run_1" : 600,
		"run_2" : 5600,
		"run_3" : 2900,
		"run_4" : 700,
		"run_10" : 1300 
	}
	var timer = 0
	var playerMap = {} 			//玩家映射
	var playerList = {} 		//玩家信息
	var runTime = 1000 			//匹配间隔
	var roomMap = {} 			//匹配房间映射
	var manager = {}
	var local = {}
	//比赛场数据
	var competitionUserList = {}		//报名人数列表
	var competitionUserMap = {} 		//报名玩家映射表
	var competitionLockList = {} 		//锁定列表
	var competitionRoomList = {} 		//比赛场房间列表
	var competitionRoomMap = {} 		//比赛场单个房间映射
	var competitionRate = {}
	for(var i in competitionCfg){
		competitionRate[i] = 1.5
	}
	competitionRate["c_a_00"] = 1
	competitionRate["c_a_15"] = 1
	competitionRate["c_a_20"] = 1.5
	competitionRate["c_a_21"] = 2
	competitionRate["c_b_03"] = 2
	competitionRate["c_b_11"] = 1.1
	competitionRate["c_b_12"] = 1.4
	competitionRate["c_b_13"] = 1.4
	competitionRate["c_b_14"] = 1.4
	//初始化
	manager.init = function() {
		for(var i in matchMap){
			matchTypeList[i] = new matchMap[i](manager)
		}
		for(var i in runQuicklyGoldCfg){
			matchTypeList[i] = new goldMatch(manager)
			runQuicklyGoldCfg[i].matchType = i
			matchTypeList[i].setInfo(runQuicklyGoldCfg[i])
			matchTypeList[i].gameMode = "hunanRunQuicklyGold"
			matchTypeList[i].gameName = i
			matchTypeList[i].expectCount = 3
			matchGoldUserNum[i] = matchGoldUserStandard[i]
		}
		for(var i in UNOGoldCfg){
			matchTypeList[i] = new goldMatch(manager)
			UNOGoldCfg[i].matchType = i
			matchTypeList[i].setInfo(UNOGoldCfg[i])
			matchTypeList[i].gameMode = "UNOGold"
			matchTypeList[i].gameName = i
			matchTypeList[i].expectCount = 6
		}
		for(var i in competitionCfg){
			competitionUserList[i] = []
		}
		manager.runMatch()
	}
	//循环定时器
	manager.mainTimer = function() {
		// console.log("mainTimer!!!")
		//概率添加比赛场机器人
		for(var cid in competitionUserList){
			var rand = Math.random()
			var tmpNum = 0
			switch(cid){
				case "c_a_00":
					tmpNum = 0.65
				break
				case "c_a_07":
					tmpNum = 0.35
				break
				case "c_a_08":
					tmpNum = 0.35
				break
				case "c_b_01":
					tmpNum = 0.4
				break
				case "c_b_02":
					tmpNum = 0.8
				break
				case "c_b_03":
					tmpNum = 0.8
				break
				case "c_b_04":
					tmpNum = 0.8
				break
				default :
					tmpNum = 0.3
				break
			}
			if(rand < tmpNum){
				local.signUpFinish(local.getRobot(),cid,function(){})
			}
		}
		var curTime = (new Date()).getTime()
		//比赛场主循环
		for(var i in competitionRoomList){
			competitionRoomList[i].mainTimer(curTime)
		}
		//金币场人数波动  时间大于23点小于8点时，基准值下降，降幅增加
		var curHour = (new Date()).getHours()
		var rate2 = 1
		if(curHour >= 23 || curHour < 8){
			rate2 = 3
		}
		var rand = Math.random()
		if(rand > 0.8){
			for(var i in matchGoldUserNum){
				var rate = 1
				if(matchGoldUserNum[i] > matchGoldUserStandard[i] / rate2 + 200){
					rate = -1
				}
				var rand2 = Math.floor(Math.random() * 20)
				if(rand > 0.95){
					rate *= -1
				}
				matchGoldUserNum[i] += rand2 * rate * rate2
			}
		}
	}
	//获取机器人ID
	local.getRobot = function() {
		var uid = Math.floor(curRobotNum + Math.random() * 10 + 1) % maxRobotNum
		if(!uid){
			uid = Math.floor(Math.random() * 10 + 1)
		}
		curRobotNum = uid
		var player = {
			"uid" : uid,
			"nickname" : robotData[uid].nickname,
			"head" : robotData[uid].head
		}
		return player
	}
	manager.setRemote = function(remote) {
		manager.remote = remote
	}
	//匹配成功
	manager.matchSuccess = function(gameType,matchType,players,info) {
		// console.log("matchSuccess")
		// console.log(gameType)
		// console.log(players)
		// console.log(info)
		var flag = false
		for(var i = 0;i < players.length;i++){
			if(players && players[i]){
				var uid = players[i].uid
				delete playerMap[uid]
				delete playerList[uid]
				if(uid > 10000){
					flag = true
				}
			}
		}
		if(flag){
			manager.remote.groupNewRoom(gameType,matchType,players,info)
		}
	}
	//启动匹配
	manager.runMatch = function() {
		clearTimeout(timer)
		timer = setInterval(manager.match,runTime)
	}
	//匹配
	manager.match = function() {
		for(var i in matchTypeList){
			matchTypeList[i].beforeRunMatch()
		}
	}
	//创建匹配房间成功
	manager.matchRoomBegin = function(roomId,matchType,players){
		if(matchTypeList[matchType]){
			roomMap[roomId] = matchType
			matchTypeList[matchType].matchRoomBegin(roomId,players)
		}
	}
	//匹配房间结束
	manager.matchRoomOver = function(roomId,info) {
		if(roomMap[roomId]){
			matchTypeList[roomMap[roomId]].matchRoomOver(roomId,info)
			delete roomMap[roomId]
		}else if(competitionRoomMap[roomId]){
			manager.competitionRoomFinish(competitionRoomMap[roomId].numeration,competitionRoomMap[roomId].RoomIndex,info.win,info.score)
			delete competitionRoomMap[roomId]
		}
	}
	//玩家退出
	manager.userQuit = function(roomId,uid) {
		var gameType = roomMap[roomId]
		if(gameType){
			matchTypeList[gameType].userQuit(roomId,uid)
		}
	}
	//获取金币场人数
	manager.getGoldMatchPlyerCounts = function() {
		var list = {}
		for(var i in matchGoldUserNum){
			list[i] = matchGoldUserNum[i]
		}
		return list
	}
	//加入匹配
	manager.joinMatching = function(player,type,info,cb) {
		if(!matchTypeList[type]){
			cb(false)
			console.log("type error : "+type)
			return
		}
		var uid = player.uid
		if(!uid || playerMap[uid]){
			cb(false,"已在匹配中")
			return
		}
		if(competitionUserMap[uid] || competitionLockList[uid]){
			cb(false,"已报名比赛")
			return
		}
		var msg = matchTypeList[type].joinMatching(player,info)
		if(msg === true){
			playerMap[uid] = type
			playerList[uid] = player
			cb(true)
		}else{
			cb(false,msg)
		}
	}
	//离开匹配
	manager.leaveMatching = function(uid,cb) {
		var type = playerMap[uid]
		if(!type){
			cb(false,"不在匹配中")
			return
		}
		matchTypeList[type].leaveMatching(uid)
		delete playerMap[uid]
		delete playerList[uid]
		cb(true)
	}
	//报名比赛场
	manager.signUp = function(uid,cid,cb) {
		if(!uid || playerMap[uid]){
			cb(false,"已在匹配中")
			return
		}
		if(competitionUserMap[uid] || competitionLockList[uid]){
			cb(false,"已报名比赛")
			return
		}
		if(competitionCfg[cid]){
			if(competitionCfg[cid].limitBeginTime){
				var curHour = (new Date()).getHours()
				if(curHour < competitionCfg[cid].limitBeginTime || curHour >= competitionCfg[cid].limitEndTime){
					cb(false,"未开放")
					return
				}
			}
			competitionUserMap[uid] = cid
			var signUpItem = competitionCfg[cid].signUpItem
			var signUpValue = competitionCfg[cid].signUpValue
			if(cid === "c_a_00"){
				var playCount = manager.getFreePlayCount(uid)
				if(playCount >= 10){
					signUpValue = 2000
				}
			}
			manager.remote.dbService.getItem(uid,signUpItem,function(data) {
				if(data === false || data < signUpValue){
					delete competitionUserMap[uid]
					// console.log(data,signUpValue,data < signUpValue)
					cb(false,"未到达报名条件")
				}else{
					//获取用户数据
					manager.remote.dbService.getPlayerInfoByUid(uid,function(data) {
						// console.log("userInfo : ",data)
						local.signUpFinish(data,cid,cb)
					})
				}
			})
		}else{
			cb(false,"比赛不存在")
		}
	}
	//取消报名
	manager.cancelSignUp = function(uid,cb) {
		if(!competitionUserMap[uid]){
			cb(false,"未报名")
			return
		}
		if(competitionLockList[uid]){
			cb(false,"无法取消")
			return
		}
		var flag = false
		var cid = competitionUserMap[uid]
		for(var i = 0;i <= competitionUserList[cid].length;i++){
			if(competitionUserList[cid][i].uid == uid){
				delete competitionUserMap[uid]
				competitionUserList[cid].splice(i,1)
				flag = true
				break
			}
		}
		var notify = {
			cmd : "signUpUpdate",
			count : competitionUserList[cid].length
		}
		if(competitionCfg[cid].needPeople <= 9){
			notify.userList = competitionUserList[cid]
		}
		for(var i = 0;i < competitionUserList[cid].length;i++){
			if(competitionUserList[cid][i].uid > 10000){
				manager.remote.sendByUid(competitionUserList[cid][i].uid,notify)
			}
		}
		if(flag === false){
			console.log(new Error("cancelSignUp error"))
			errorLogger.info("cancelSignUp error : "+uid)
			cb(false)
		}else{
			cb(true)
		}
	}
	//报名成功
	local.signUpFinish = function(userInfo,cid,cb) {
		var notify = {
			cmd : "signUpFinish",
			userInfo : userInfo
		}
		for(var i = 0;i < competitionUserList[cid].length;i++){
			if(competitionUserList[cid][i].uid > 10000){
				manager.remote.sendByUid(competitionUserList[cid][i].uid,notify)
			}
		}
		competitionUserList[cid].push(userInfo)
		var info = {
			cid : cid,
			count : competitionUserList[cid].length
		}
		if(competitionCfg[cid].needPeople <= 9){
			info.userList = competitionUserList[cid]
		}
		cb(true,info)
		if(competitionUserList[cid].length == competitionCfg[cid].needPeople){
			local.competitionBegin(cid)
		}
	}
	//满人开赛
	local.competitionBegin = function(cid){
		var users = competitionUserList[cid]
		//清空队列
		competitionUserList[cid] = []
		var numeration = cid+":"+UUID.v1()
		var signUpItem = competitionCfg[cid].signUpItem
		var signUpValue = competitionCfg[cid].signUpValue
		var participationItem = competitionCfg[cid].participationItem
		var participationValue = competitionCfg[cid].participationValue
		var flag = false
		for(var i in users){
			if(users[i].uid > 10000){
				flag = true
				competitionLockList[users[i].uid] = numeration
				delete competitionUserMap[users[i].uid]
				var tmpSignUpValue = signUpValue
				if(cid === "c_a_00"){
					var playCount = manager.getFreePlayCount(users[i].uid)
					if(playCount > 10){
						tmpSignUpValue = 2000
					}
					manager.addFreePlayCount(users[i].uid)
				}
				//扣除报名费
				manager.remote.app.rpc.db.remote.addItemReason(null,users[i].uid,signUpItem,-tmpSignUpValue,"比赛场报名:"+cid,null)
				//获得比赛场积分
				manager.remote.app.rpc.db.remote.addItemReason(null,users[i].uid,participationItem,participationValue,"参与比赛:"+cid,null)
				//记录参与次数
				manager.remote.app.rpc.db.gameInfo.setRunCPlay(null,users[i].uid,cid,participationValue,function(){})
				//增加库存
				manager.remote.dbService.db.hincrby("game:competition:inventory",cid,1)
			}
		}
		if(flag){
			// console.log("满人开赛",users)
			competitionRoomList[numeration] = new competitionMatch(manager)
			competitionRoomList[numeration].init(cid,numeration,users,3,"hunanRunQuicklyCompetition")
			// console.log("competitionRoomList ： ",competitionRoomList)
		}
	}
	//比赛完成，发放奖励
	manager.competitionFinish = function(numeration,winUid,players) {
		var cid = competitionRoomList[numeration].cid
		var signUpItem = competitionCfg[cid].signUpItem
		var signUpValue = competitionCfg[cid].signUpValue
		var championAwardItem = competitionCfg[cid].championAwardItem
		var championAwardValue = competitionCfg[cid].championAwardValue
		var secondAwardItem = competitionCfg[cid].secondAwardItem
		var secondAwardValue = competitionCfg[cid].secondAwardValue
		var cName = competitionCfg[cid].name
		// console.log("冠军奖励",winUid)
		// console.log(championAwardItem,championAwardValue,secondAwardItem,secondAwardValue)
		if(championAwardItem && championAwardValue && winUid > 10000){
			var info = {}
			info[championAwardItem] = championAwardValue
			// console.log("冠军奖励222",info,winUid)
			manager.remote.app.rpc.db.mail.sendMail(null,winUid,cName+"冠军","恭喜您战胜全部对手，成功赢得冠军，这是您的奖励，下次继续加油!",info,null)
			manager.remote.dbService.db.hincrbyfloat("game:competition:inventory",cid,parseInt(-competitionCfg[cid].needPeople * competitionRate[cid]) || 1)
			//记录夺冠次数
			manager.remote.app.rpc.db.gameInfo.setRunCChampion(null,winUid,cid,championAwardItem,championAwardValue,function(){})
		}
		//亚军
		for(var i in players){
			if(players[i].uid != winUid && players[i].uid > 10000){
				if(secondAwardItem && secondAwardValue){
					var info = {}
					info[secondAwardItem] = secondAwardValue
					manager.remote.app.rpc.db.mail.sendMail(null,players[i].uid,cName+"亚军","恭喜您战胜对手，成功取得亚军，这是您的奖励，下次继续加油!",info,null)
					manager.remote.dbService.db.hincrbyfloat("game:competition:inventory",cid,parseInt(-competitionCfg[cid].needPeople * competitionRate[cid] / 3) || 1)
				}
				//记录亚军次数
				manager.remote.app.rpc.db.gameInfo.setRunCSecond(null,players[i].uid,cid,secondAwardItem,secondAwardValue,function(){})
			}
		}
		console.log("competitionFinish : ",numeration,winUid,"发放奖励","cid",cid)
		//记录后台数据  对阵表  奖励
		var messageInfo = {
			messageType : "competitionFinish",
			counterpartTable : competitionRoomList[numeration].allCounterpartTable,
			signUpItem : signUpItem,
			signUpValue : signUpValue,
			championAwardItem : championAwardItem,
			championAwardValue : championAwardValue,
			secondAwardItem : secondAwardItem,
			secondAwardValue : secondAwardValue,
			winUid : winUid,
			time : (new Date()).getTime(),
			cName : cName,
			cid : cid
		}
		manager.remote.app.rpc.db.cacheMessage.writeMessage(null,JSON.stringify(messageInfo),function(){})
		delete competitionRoomList[numeration]
	}
	//小局比赛开始
	manager.groupNewCompetitionRoom = function(numeration,RoomIndex,curRound,maxRound,users,gameType,cid) {
		var roomId = numeration+":"+curRound+":"+RoomIndex
		competitionRoomMap[roomId] = {
			numeration : numeration,
			RoomIndex : RoomIndex
		}
		manager.remote.groupNewCompetitionRoom(numeration,RoomIndex,curRound,maxRound,users,gameType,roomId,cid)
	}
	//小局比赛结束
	manager.competitionRoomFinish = function(numeration,RoomIndex,win,score){
		if(competitionRoomList[numeration]){
			competitionRoomList[numeration].competitionRoomFinish(RoomIndex,win,score)
		}else{
			// console.log("competitionRoomList[numeration] error",competitionRoomList,numeration)
		}
	}
	//比赛结束解锁玩家
	manager.deblocking = function(uid){
		// console.log("deblocking : "+uid)
		if(competitionLockList[uid]){
			delete competitionLockList[uid]
			delete competitionUserMap[uid]
		}else if(uid > 10000){
			new Error("deblocking error : "+uid+"  : "+JSON.stringify(competitionLockList))
			errorLogger.info("deblocking error : "+uid+"  : "+JSON.stringify(competitionLockList))
		}
	}
	//获取比赛场报名人数信息
	manager.getCompetitionList = function(cb) {
		var info = {}
		for(var cid in competitionUserList){
			info[cid] = competitionUserList[cid].length
		}
		cb(true,info)
	}
	//获取我的比赛场信息
	manager.getCompetitionInfo = function(uid,cb) {
		if(!competitionLockList[uid] && !competitionUserMap[uid]){
			cb(false,"未进入比赛场")
			return
		}
		if(competitionUserMap[uid]){
			var cid = competitionUserMap[uid]
			cb(true,{"waitFlag" : true,"cid" : cid,"userList" : competitionUserList[cid],count : competitionUserList[cid].length})
			return
		}
		var numeration = competitionLockList[uid]
		if(competitionRoomList[numeration]){
			competitionRoomList[numeration].getCompetitionInfo(cb)
		}else{
			cb(false,"比赛不存在")
		}
	}
	//获取我的比赛场阶段
	manager.getCompetitionState = function(uid) {
		if(competitionUserMap[uid]){
			return "competitionSignUp"
		}
		var numeration = competitionLockList[uid]
		if(competitionRoomList[numeration]){
			return "competitionWaiting"
		}
		return false
	}
	//获取指定比赛场信息
	manager.getCompetitionInfoByNumeration = function(numeration,cb) {
		if(competitionRoomList[numeration]){
			competitionRoomList[numeration].getCompetitionInfo(cb)
		}else{
			cb(false,"比赛不存在")
		}
	}
	//获取全部比赛场
	manager.getCompetitionAll = function(cb) {
		var arr = []
		for(var i in competitionRoomList){
			arr.push(i)
		}
		cb(true,arr)
	}
	manager.addFreePlayCount = function(uid) {
		manager.updateFreePlayCounts()
		if(!freePlayCounts[uid]){
			freePlayCounts[uid] = 0
		}
		freePlayCounts[uid]++
	}
	manager.getFreePlayCount = function(uid) {
		manager.updateFreePlayCounts()
		return freePlayCounts[uid] || 0
	}
	manager.updateFreePlayCounts = function() {
		var curDate = (new Date()).getDate()
		if(freePlayDate !== curDate){
			freePlayDate = curDate
			freePlayCounts = {}
		}
	}
  	app.set("matchManager",manager)
	return manager
}